﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.ComponentModel;
using System.Collections.ObjectModel;
using CookComputing.XmlRpc;
using System.Reflection;
using System.Threading;
using System.IO;
using Microsoft.Phone.Marketplace;
using Microsoft.Phone.Net;



namespace HomeWP
{
    public partial class MainPage : PhoneApplicationPage
    {
        private HomeMaticData hmData = ((App)App.Current).HMData;
        private HMDataContext hMDB = ((App)App.Current).HMData.DataContext;
        private CCUSettings CCUSet;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            hmData = ((App)App.Current).HMData;

            // Data context and observable collection are children of the main page.
            this.DataContext = this;

            if (hMDB.HMCCUSettings.Count(t => t.ConfigID == "TEST") > 0)
            {
                CCUSet = hMDB.HMCCUSettings.Single(t => t.ConfigID == "TEST");
            }

            hmData.FavoriteChanged += hmData_FavoriteChanged;

        }

   

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            try
            {
                if (!Microsoft.Phone.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
                {
                    MessageBox.Show("Keine Netzerkverbindung vorhanden!", "Verbindungsfehler", MessageBoxButton.OK);
                }

                if (!hmData.CheckHasHMData())
                    NavigationService.Navigate(new Uri("/Welcome.xaml", UriKind.Relative));

                ShowHideFavortiesPivot();

                if (hMDB.HMCCUSettings.Count(t => t.ConfigID == "TEST") > 0)
                    CCUSet = hMDB.HMCCUSettings.Single(t => t.ConfigID == "TEST");


                // Call the base method.
                base.OnNavigatedTo(e);
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }

        void hmData_FavoriteChanged()
        {
            ShowHideFavortiesPivot();
        }

        private void ShowHideFavortiesPivot()
        {
            if (hmData.DataContext.HMFavorite.Count() == 0)
            {
                if (p_Main.Items.Any(t => t == pi_Favorites))
                    p_Main.Items.Remove(pi_Favorites);
            }
            else
            {
                if (!p_Main.Items.Any(t => t == pi_Favorites))
                    p_Main.Items.Add(pi_Favorites);
            }
        }

        private void p_Main_LoadingPivotItem(object sender, PivotItemEventArgs e)
        {
            ShowHideFavortiesPivot();
            if (e.Item == pi_Favorites)
                ShowFavorites();

            if (e.Item == pi_Rooms)
                ShowRooms();

            if (e.Item == pi_Functions)
                ShowFunctions();
            if (e.Item == pi_Variables)
                ShowVariables();
            /*  if (e.Item == pi_Devices)
                  ShowDevices();*/

        }


        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            // Call the base method.
            base.OnNavigatedFrom(e);

            // Save changes to the database.
            try
            {
                hMDB.SubmitChanges();
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }


        private void ShowRooms()
        {
            // Execute the query and place the results into a collection.
            var HMRooms = new ObservableCollection<DeviceRoom>(from DeviceRoom oItem in hMDB.HMRoom select oItem);
            sp_Rooms.Children.Clear();
            try
            {

                List<string> lRooms = new List<string>();
                foreach (DeviceRoom dRoom in hMDB.HMRoom.OrderBy(t => t.RoomName).ToList())
                {
                    if (!lRooms.Contains(dRoom.RoomName))
                    {
                        var g_Room = new StackPanel();
                        g_Room.DataContext = dRoom;
                        var tb_Title = new TextBlock();
                        tb_Title.Style = Resources["GroupHeader"] as Style;
                        tb_Title.Text = dRoom.RoomName;
                        if (dRoom == hMDB.HMRoom.First())
                            tb_Title.Margin = new Thickness(0, 0, 0, 8);
                        else
                            tb_Title.Margin = new Thickness(0, 16, 0, 8);
                        g_Room.Children.Add(tb_Title);
                        sp_Rooms.Children.Add(g_Room);
                        lRooms.Add(dRoom.RoomName);
                    }
                }

                foreach (StackPanel spItem in sp_Rooms.Children.Where(c => c is StackPanel))
                    AddHMItemsToList(spItem);


            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }

        }


        private void ShowFavorites()
        {
            try
            {
                sp_Favorites.Children.Clear();
                var Devices = new ObservableCollection<Device>
                    //            ( from Device aDevice in hMDB.HMDevices  where aDevice.Address.Contains(Favs.Address) select aDevice)
                   (from Device aDevice in hMDB.HMDevices
                    join Favorite f in hMDB.HMFavorite on aDevice.Address equals f.Address
                    select aDevice)
                    .Where(t => !string.IsNullOrEmpty(t.DisplayName))
                    .OrderBy(t => t.DisplayName)
                    .ToList();
                string sType = "";
                foreach (Device aDevice in Devices)
                {
                    StackPanel sp1 = new StackPanel();
                    sType = AddDevice(sp1, sType, aDevice);
                    sp_Favorites.Children.Add(sp1);
                }
            }
            catch { }


        }


        private void ShowFunctions()
        {
            // Execute the query and place the results into a collection.
            var HMFunction = new ObservableCollection<DeviceFunction>(from DeviceFunction oItem in hMDB.HMFunction select oItem);

            sp_Functions.Children.Clear();
            try
            {

                List<string> lFunction = new List<string>();
                foreach (DeviceFunction aFunction in hMDB.HMFunction.OrderBy(t => t.Function).ToList())
                {
                    if (!lFunction.Contains(aFunction.Function))
                    {
                        var g_Function = new StackPanel();
                        g_Function.DataContext = aFunction;
                        var tb_Title = new TextBlock();
                        tb_Title.Style = Resources["GroupHeader"] as Style;
                        tb_Title.Text = aFunction.Function;
                        g_Function.Children.Add(tb_Title);
                        sp_Functions.Children.Add(g_Function);

                        lFunction.Add(aFunction.Function);
                    }
                }

                foreach (StackPanel spItem in sp_Functions.Children.Where(c => c is StackPanel))
                {
                    string sFunction = ((DeviceFunction)spItem.DataContext).Function;
                    if (hMDB.HMFunction.Count(t => t.Function == sFunction) > 0)
                    {
                        StackPanel sp1 = new StackPanel();
                        List<Device> DevItems = new List<Device>
                                (from oi in hMDB.HMFunction
                                 join c in hMDB.HMDevices on oi.Address equals c.Address
                                 where oi.Function == sFunction
                                 select c);

                        string sType = "";
                        foreach (Device oDevice in DevItems.OrderBy(t => t.DisplayName).ThenBy(t => t.Type))
                        {
                            sType = AddDevice(sp1, sType, oDevice);
                        }

                        spItem.Children.Add(sp1);
                    }
                }
            }



            catch (Exception ex)
            {
                ex.Message.ToString();
            }

        }

        private void ShowVariables()
        {
            var HMVariables = new ObservableCollection<SystemVariable>(from SystemVariable oItem in hMDB.HMVariables_ select oItem);
            spVars.Children.Clear();

            foreach (SystemVariable oVar in HMVariables.Where(t => t.Visible == true))
            {
                VariableControl VarCtr = new VariableControl();
                //VarCtr.HMVar = oVar;
                VarCtr.DataContext = oVar;
                spVars.Children.Add(VarCtr);
                spVars.Children.Add(new HMSeparator());
            }
        }

        private void ShowDevices()
        {

            /*    try
                {
                    // Define the query to gather all of the to-do items.
                    var HMItemsInDB = from Device todo in hMDB.HMDevices select todo;

                    // Execute the query and place the results into a collection.
                    var HMDevices = new ObservableCollection<Device>(from Device oItem in hMDB.HMDevices select oItem);
                    //HMDeviceNames = new ObservableCollection<DeviceName>(from DeviceName oItem in hMDB.HMDeviceName select oItem);

                    //lSwitch = HMDevices.Where(t => t.Type == "SWITCH").ToList();
                    List<Device> lDevices = HMDevices.Where(t => !string.IsNullOrEmpty(t.DisplayName)).ToList();

                    var DevByType = from dev in lDevices group dev by dev.Type into c orderby c.Key select new Group<Device>(c.Key, c);

                    //longListSelector1.ItemsSource = HMDevices.Select(t => t.Type;
                    var DeviceList = DevByType.ToObservableCollection();
                    lls_Devices.ItemsSource = DeviceList;

                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }*/
        }

        public class Group<T> : ObservableCollection<T>
        {
            public Group(string name, IEnumerable<T> items)
            { this.Key = name; foreach (T item in items) { this.Add(item); } }
            public override bool Equals(object obj)
            { Group<T> that = obj as Group<T>; return (that != null) && (this.Key.Equals(that.Key)); }
            public string Key
            {
                get;
                set;

            }
        }

        private void AddHMItemsToList(StackPanel spItem)
        {
            string sRoom = ((DeviceRoom)spItem.DataContext).RoomName;
            StackPanel sp1 = new StackPanel();
            List<String> oItems = hMDB.HMRoom.Where(t => t.RoomName == sRoom).Select(t => t.Address).ToList();

            oItems.Sort();
            List<Device> RoomItems = new List<Device>();
            foreach (string sAddr in oItems)
            {
                try
                {
                    Device oDevice = hMDB.HMDevices.Single(t => t.Address == sAddr);
                    RoomItems.Add(oDevice);
                }
                catch (Exception ex)
                {
                    ex.Message.ToString();
                }
            }

            string sType = "";
            foreach (Device oDevice in RoomItems.OrderBy(t => t.DisplayName).ThenBy(t => t.Type))
            {
                sType = AddDevice(sp1, sType, oDevice);
            }

            spItem.Children.Add(sp1);
        }

        private string AddDevice(StackPanel sp1, string sType, Device oDevice)
        {
            //Add Devices
            if (oDevice.Type == "SWITCH")
            {
                SWITCH tb1 = new SWITCH();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.HMDevice = oDevice;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "DIMMER")
            {
                DIMMER tb1 = new DIMMER();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "SMOKE_DETECTOR")
            {
                SmokeDetector tb1 = new SmokeDetector();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "SMOKE_DETECTOR_TEAM")
            {
                SmokeDetector tb1 = new SmokeDetector();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "WEATHER")
            {
                HMWeather tb1 = new HMWeather();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.HMDevice = oDevice;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "BLIND")
            {
                BLIND tb1 = new BLIND();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.HMDevice = oDevice;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;

                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "KEY")
            {
                HMKey tb1 = new HMKey();
                tb1.Address = oDevice.Address;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                if (oDevice.DisplayName.Contains(':'))
                {
                    tb1.DisplayName = oDevice.DisplayName.Split(':')[0];
                    tb1._button.Content = oDevice.DisplayName.Split(':')[1];
                }
                else
                {
                    tb1.DisplayName = oDevice.DisplayName;
                }
                tb1.HMDevice = oDevice;

                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "MOTION_DETECTOR")
            {
                HMMDIR tb1 = new HMMDIR();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.HMDevice = oDevice;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "INPUT_OUTPUT")
            {
                //Output
                if (oDevice.Direction == 2)
                {
                    SWITCH tb1 = new SWITCH();
                    tb1.Address = oDevice.Address;
                    tb1.DisplayName = oDevice.DisplayName;
                    tb1.CCUIP = CCUSet.CCU;
                    if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                        tb1.CCUPort = 2001;
                    else
                        tb1.CCUPort = 2000;
                    sp1.Children.Add(tb1);
                }
            }

            if (oDevice.Type == "SHUTTER_CONTACT")
            {
                SHUTTERCONTACT tb1 = new SHUTTERCONTACT();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            if (oDevice.Type == "ROTARY_HANDLE_SENSOR")
            {
                ROTARYHANDLE tb1 = new ROTARYHANDLE();
                tb1.Address = oDevice.Address;
                tb1.DisplayName = oDevice.DisplayName;
                tb1.CCUIP = CCUSet.CCU;
                if (string.Compare(oDevice.Bus, "RF", StringComparison.InvariantCultureIgnoreCase) == 0)
                    tb1.CCUPort = 2001;
                else
                    tb1.CCUPort = 2000;
                sp1.Children.Add(tb1);
            }

            //Add Separator
            if (sp1.Children.Count > 0)
            {
                if (sp1.Children.Last().GetType() != typeof(HMSeparator))
                {
                    sp1.Children.Add(new HMSeparator());
                }
            }

            sType = oDevice.Type;
            return sType;
        }




        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        // Used to notify Silverlight that a property has changed.
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        private void abmiSettings_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/Settings.xaml", UriKind.Relative));
        }



    }
}